
import RTC from './RTC';
import HttpPost from '@/thirdjs/http.js'
export default class SFU{

    constructor(userId,roomId){
        this._rtc = new RTC();
		this.post = false;
        var sfuUrl = "wss://localhost:3000/ws?userId=" + userId + "&roomId=" + roomId;
		// 第三步，初始化信令连网
        this.socket = new WebSocket(sfuUrl);

        this.socket.onopen = () => {
            console.log("WebSocket连接成功...");
			//第四步，执行信令连网链接
            this._onRoomConnect();
        };

        this.socket.onmessage = (e) => {
            var parseMessage = JSON.parse(e.data);

            switch(parseMessage.type){
                case 'joinRoom':
                    console.log(parseMessage);
                    break;
                case 'onJoinRoom':
					//第十步，服务器返回加入房间成功消息
                    console.log("onJoinRoom=")
					console.log(parseMessage);
                    break;   
                case 'onPublish':
					//第十一步，服务器返回房间里面的发布者
					//第L步，publish后，服务器返回onPublish
                    this.onPublish(parseMessage);
                    break;
                case 'onUnpublish':
                    this.onUnpublish(parseMessage);
                    break;
                case 'onSubscribe':
                    this.onSubscribe(parseMessage);
                    break; 
                case 'heartPackage':
                    console.log("heartPackage:::");
                    break; 
                default:
                    console.error('未知消息',parseMessage);
            }
        };

        this.socket.onerror = (e) => {
            console.log('onerror::' + e.data);
        };

        this.socket.onclose = (e) => {
            console.log('onclose::' + e.data);
        };
    }


    _onRoomConnect = () => {
        console.log('onRoomConnect');
		//第f步，执行回调播放本地视频流源
        uni.$on('localstream',(id,stream) => {
            uni.$emit('addLocalStream',id,stream);
        })
		//第二十一步，
        uni.$on('addstream',(id,stream) => {
            uni.$emit('addRemoteStream',id,stream);
        })

        uni.$on('removestream',(id,stream) => {
            uni.$emit('removeRemoteStream',id,stream);
        })
		//第五步，执行信令连网链接回调，调用加入房间
        uni.$emit('connect');
    }
	//第七步，执行join加入房间
    join(userId,userName,roomId){
        console.log('Join to [' + roomId + ']');
        this.userId = userId;
        this.userName = userName;
        this.roomId = roomId;

        let message = {
            'type':'join',
            'data':{
                'userName':userName,
                'userId':userId,
                'roomId':roomId,
            }
        };
		//第八步，调用发送给服务器指令
        this.send(message);

    }
	// 第九步，所有的发送服务器的公共方法
    send = (data) => {
        this.socket.send(JSON.stringify(data));
    }

	//第b步，调用发布者
    publish(){
        this._createSender(this.userId);
    }
	//第X2步，post调用发布者
    publishPost(userId,roomId,userName){
		this.post = true;
		this.roomId = roomId;
		this.userId = userId;
		this.userName = userName;
        this._createSender(userId);
    }
    async _createSender(pubid){

        try{
            //第c步，创建一个sender
            let sender = await this._rtc.createSender(pubid);
            this.sender = sender;

            //第i步，监听IceCandidate回调
            sender.pc.onicecandidate = async (e) => {
				console.log('sender.pc.onicecandidate =>' + e.candidate);
                if(!sender.offerSent){
                    var offer = sender.pc.localDescription;
                    sender.offerSent = true;
					//第j步，把本地sdp发送给服务器
					await this.publishToServer(offer,pubid);
                }
            }
            //第h步，创建自己作为发布者的Offer，并设置onice回调
            let desc = await sender.pc.createOffer({ offerToReceiveVideo:false,offerToReceiveAudio:false})
            sender.pc.setLocalDescription(desc);

        }catch(error){
            console.log('onCreateSender error =>' + error);
        }

    }

    async publishToServer(offer,pubid){
		if (this.post) {
			//第x3步，post请求
			let data = {
				'type':'publish',
				'data':{
				    'jsep':offer,
				    'pubid':pubid,
				    'userName':this.userName,
				    'userId':this.userId,
				    'roomId':this.roomId,
				}
			};
			HttpPost.http(
					"/offer",
					data,
					'POST',
					{
						"Content-Type": "application/json; charset=UTF-8",
					}
			).then(res => {
				console.log(res);
				//打印请求返回的数据
			}, error => {
				console.log("http post error ihero");
				console.log(error);
			});
			
			this.post = false;
			return;
		}
        let message = {
            'type':'publish',
            'data':{
                'jsep':offer,
                'pubid':pubid,
                'userName':this.userName,
                'userId':this.userId,
                'roomId':this.roomId,
            }
        };
		//第k步，发送给服务端publish
        this.send(message);
    }

    onPublish(message){

        //服务器返回的Answer信息 如A--->Offer--->SFU--->Answer--->A
        if(this.sender && message['data']['userId'] == this.userId){
            console.log('onPublish:::自已发布的Id:::' + message['data']['userId']);
            this.sender.pc.setRemoteDescription(message['data']['jsep']);
        }
		//第十二步，返回房间所有的发布者，服务端for循环返回调用
        //服务器返回其他人发布的信息 
		//如A--->Pub--->SFU--->my & B--->Pub--->SFU--->my ……
        if(message['data']['userId'] != this.userId){
            console.log('onPublish:::其他人发布的Id:::' + message['data']['userId']);
            //第十三步，使用发布者的userId（pubid）创建Receiver
            this._onRtcCreateReceiver(message['data']['userId']);
        }

    }

    onUnpublish(meesage){
        console.log('退出用户:'+meesage['data']['pubid']);
        this._rtc.closeReceiver(meesage['data']['pubid']);
    }

    async _onRtcCreateReceiver(pubid) {
        try{
			//第十四步,创建接受视频track通道
            let receiver = await this._rtc.createReciver(pubid);
           
            receiver.pc.onicecandidate = async (e) => {
				//第十八步，回调添加receiver stream流
				console.log('SFU receiver.pc.onicecandidate =>'
					+ e.candidate);
				//console.log(e.candidate);
                if(!receiver.offerSent){
                    var offer = receiver.pc.localDescription;
                    receiver.offerSent = true;
					console.log('SFU receiver offer =>' + offer);
					console.log(offer);
                    await this.subscribeFromServer(offer,pubid);
                }
            }
            //第十七步，创建Offer，设置本地描述，创建onicecandidate回调
            let desc = await receiver.pc.createOffer();
            receiver.pc.setLocalDescription(desc);

        }catch(error){
            console.log('onRtcCreateReceiver error =>' + error);
        }
    }

    
    async subscribeFromServer(offer,pubid){
        let message = {
            'type':'subscribe',
            'data':{
                'jsep':offer,
                'pubid':pubid,
                'userName':this.userName,
                'userId':this.userId,
                'roomId':this.roomId,
            }
        };
        this.send(message);
    }


    onSubscribe(message){
        //使用发布者的Id获取Receiver
        var receiver = this._rtc.getReceivers(message['data']['pubid']);
        if(receiver){
            console.log('服务器应答Id:' + message['data']['pubid']);
            receiver.pc.setRemoteDescription(message['data']['jsep']);
        }else{
            console.log('receiver == null');
        }
    }

}